package org.demo.cnck.controller.error;

import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.demo.cnck.controller.vm.HttpResult;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

import java.util.List;
import java.util.stream.Collectors;

/**
 * Controller advice to translate the server side exceptions to client-friendly json structures.
 */
@Controller
@ControllerAdvice
public class GlobalDefaultExceptionHandler {


    @ExceptionHandler(UnauthorizedException.class)
    public String unauthorizedExceptionError(UnauthorizedException unauthorized) {
        return "login";
    }

    @ExceptionHandler(SystemException.class)
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public HttpResult SystemExceptionError(SystemException systemException) {
        return HttpResult
                .builder()
                .code(HttpStatus.INTERNAL_SERVER_ERROR.value())
                .message(systemException.getMessage())
                .result(HttpResult.Result.FAIL)
                .build();
    }

    @ExceptionHandler(BussinessException.class)
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public HttpResult bussinessExceptionError(BussinessException buss) {
        return HttpResult
                .builder()
                .code(HttpStatus.BAD_REQUEST.value())
                .message(buss.getMessage())
                .result(HttpResult.Result.FAIL)
                .build();
    }


    @ExceptionHandler(DataNotFoundException.class)
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public HttpResult dataNotFoundExceptionError(DataNotFoundException buss) {
        return HttpResult
                .builder()
                .code(HttpStatus.NOT_FOUND.value())
                .message(buss.getMessage())
                .result(HttpResult.Result.FAIL)
                .build();
    }

    @ExceptionHandler(NoPermissionException.class)
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public HttpResult noPermissionExceptionError(NoPermissionException buss) {
        return HttpResult
                .builder()
                .code(HttpStatus.FORBIDDEN.value())
                .message(buss.getMessage())
                .result(HttpResult.Result.FAIL)
                .build();
    }


    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public HttpResult methodArgumentNotValidExceptionError(MethodArgumentNotValidException methodArgument) {
        List<String> errors = methodArgument.getBindingResult().getAllErrors().stream().map(error -> {
            String jsonError = JSONObject.toJSONString(error);
            JSONObject errorObj = JSONObject.parseObject(jsonError);
            return errorObj.getString("defaultMessage");
        }).collect(Collectors.toList());
        return HttpResult
                .builder()
                .code(HttpStatus.BAD_REQUEST.value())
                .message(StringUtils.join(errors, ";"))
                .result(HttpResult.Result.FAIL)
                .build();
    }


}
